<!DOCTYPE html>
<html>
<head>
    <title>在线转换</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://cdn.bootcss.com/pure/1.0.0/base-min.css">
    <link rel="stylesheet" href="https://cdn.bootcss.com/pure/1.0.0/pure-min.css" crossorigin="anonymous">

    <!--[if lte IE 8]>
    <link rel="stylesheet" href="https://cdn.bootcss.com/pure/1.0.0/grids-responsive-old-ie-min.css">
    <![endif]-->
    <!--[if gt IE 8]><!-->
    <link rel="stylesheet" href="https://cdn.bootcss.com/pure/1.0.0/grids-responsive-min.css">
    <!--<![endif]-->

    <link rel="stylesheet" href="./demo/style.css">

    <script type="text/javascript" src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    <script type="text/javascript" src="https://cdn.bootcss.com/jszip/3.1.5/jszip.js"></script>
    <script type="text/javascript" src="./demo/midi-parser.js"></script>

    <script type="text/javascript">
        window._message = function (message, level) {
            var cls = '';
            var lv = (function (lv) {
                if (lv) {
                    if (lv === 1 || lv === 'warn') {
                        cls = 'warn';
                        return '警告';
                    }
                    if (lv === 2 || lv === 'error') {
                        cls = 'error';
                        return '错误';
                    }
                }
                return '信息';
            })(level);
            var time = function () {
                var fix = function (v) {
                    return v < 10 ? ('0' + v) : (v + '');
                };
                var date = new Date();
                var h = date.getHours(), m = date.getMinutes(), s = date.getSeconds(), i = date.getMilliseconds();
                return fix(h) + ':' + fix(m) + ':' + fix(s) + '.' + fix(i);
            };
            var msg = time() + ' ' + lv + ': ' + message;
            $('#_message').append($('<span>' + msg + '</span>').addClass(cls)).scrollTop(function () {
                return this.scrollHeight;
            });
        };
    </script>

    <script type="text/javascript" src="./demo/translator.js"></script>

    <script type="text/javascript">
        $(function () {
            function toHex(array) {
                var v = [];
                array.forEach(function (item) {
                    var hex = item.toString(16);
                    if (hex.length === 1) {
                        v.push('0');
                    }
                    v.push(hex);
                });
                return v.join('').toUpperCase();
            }

            function unzip(data) {
                JSZip.loadAsync(data).then(function (zip) {
                    zip.file('META-INF/container.xml').async('text').then(function (xml) {
                        var doc = $.parseXML(xml);
                        var root = new MXL.Element(doc.documentElement).select('/container/rootfiles/rootfile');
                        if (root.length) {
                            var path = root[ 0 ].attr('full-path');
                            zip.file(path).async('text').then(function (mxl) {
                                $('#_source').data('type', 'mxl').val(mxl || '');
                            });
                        }
                    });
                }, function (e) {
                    _message(e.message, 2);
                });
            }

            function clear() {
                return $('#_message').empty();
            }

            var midi;

            $('#_upload').on('change', function (e) {
                midi = null;
                var file = e.target.files[ 0 ];
                var name = file.name;
                clear();
                _message('开始读取文件: ' + name);
                if (window.FileReader) {
                    var src = $('#_source').removeData();
                    var reader = new FileReader();
                    reader.onloadend = function () {
                        _message('文件读取完毕,尝试解析...');

                        var data = new Uint8Array(reader.result);
                        var magic = toHex(data.subarray(0, 4));
                        if ('3C3F786D' === magic) {//XML
                            var dec = new TextDecoder('UTF-8');
                            src.data('type', 'mxl').val(dec.decode(data) || '');
                            _message('解析为 MusicXML');
                        } else if ('504B0304' === magic) {//ZIP
                            unzip(data);
                            _message('解析为 Compression MusicXML');
                        } else if ('4D546864' === magic) {//MIDI
                            midi = MIDIParser.parse(data);
                            src.data('type', 'mid').val(JSON.stringify(midi));
                            _message('解析为 MIDI');
                        } else {
                            _message('未知的文件类型: ' + magic, 2);
                        }
                    };
                    reader.onerror = function () {
                        _message(reader.error.message, 2);
                    };

                    if (file) {
                        src.data('name', name);
                        $('#_sourceName').text(name);
                        reader.readAsArrayBuffer(file);
                    }
                } else {
                    _message('你的浏览器太落后了,请自行将MusicXML的内容粘贴到Source', 2);
                }
            });
            $('#_translate').on('click', function () {
                _message('开始转换...');
                console.log('Translate...');

                var src = $('#_source');
                var data = src.val();
                var target = $('#_target').val('');

                var cfg = {};
                $.each($('#_cfg').serializeArray(), function (_, o) {
                    cfg[ o.name ] = o.value;
                });

                if (cfg.name) {
                    src.data('name', cfg.name);
                }
                cfg.type = src.data('type');
                var translator;
                if (cfg.type === 'mid') {
                    translator = new SMF.Translator(midi ? midi : data, cfg);
                } else {
                    translator = new MXL.Translator(data, cfg);
                }
                if (translator) {
                    console.log('Start...');
                    var result = translator.translate();
                    target.val(result || '');
                    console.log('Finish');
                    _message('转换完毕');
                } else {
                    _message('找不到有效的转换器', 2);
                }
            });
            $('#_anchor').on('click', function () {
                var anchor = this;
                var val = $('#_target').val();
                var blob = new Blob([ val ], { type : 'text/plain' });
                anchor.download = ($('#_source').data('name') || '无名') + '.gjm';
                anchor.href = (window.webkitURL || window.URL).createObjectURL(blob);
                anchor.dataset.downloadurl = [ 'text/plain', anchor.download, anchor.href ].join(':');
            });
            $('#_speed').on('change, mouseup, keyup, blur, click', function () {
                var num = parseInt($(this).val());
                if (num) {
                    num = Math.max(50, Math.min(300, num));
                } else {
                    num = 100;
                }
                $(this).val(num);
            });

            var noteURL = './demo/notes.json';//'http://127.0.0.1:8887/notes.json';
            $.getJSON(noteURL, function (data) {
                if ($.isArray(data)) {
                    var make = function (note) {
                        var div = $('<div class="note"></div>');
                        div.append('<div class="date">' + note.time + '</div>');
                        $.each({
                            'update' : '更新',
                            'fix' : '修正',
                            'todo' : '计划'
                        }, function (name, title) {
                            var data = note[ name ];
                            if ($.isArray(data) && data.length) {
                                div.append('<span>' + title + ':</span>');
                                var ul = $('<ul class="' + name + '">').appendTo(div);
                                $.each(data, function (_, v) {
                                    ul.append('<li>' + v + '</li>');
                                });
                            }
                        });
                        return div;
                    };
                    var showCount = 3;
                    var array = data.reverse(), len = array.length;
                    var ns = $('.notes');
                    for (var i = 0, max = Math.min(showCount, len); i < max; i++) {
                        ns.append(make(array[ i ]));
                    }
                    if (len > showCount) {
                        var btn = $('<a href="javascript:void(0);" class="pure-button">更多...</a>').appendTo(ns);
                        btn.on('click', function () {
                            $(this).remove();
                            for (var i = showCount, max = len; i < max; i++) {
                                ns.append(make(array[ i ]));
                            }
                        });
                    }
                }
            });
        });
    </script>
</head>
<body>

<div class="pure-g">
    <div class="pure-u-1">
        <h2>MusicXML / MXL(压缩过的MusicXML) / MIDI(初步支持) -> GJM</h2>
        <p>不要使用 <b style="color:red;">IE</b> !!!, 详细情况见
            <a href="http://bbs.ngacn.cc/read.php?tid=14725485" target="_blank">我的帖子</a>
        </p>
    </div>
    <div class="pure-u-1 pure-u-md-1-3">
        <form class="pure-form pure-form-stacked" action="#">
            <label for="_upload" class="pure-button">打开...</label>
            <input id="_upload" type="file" hidden/>
            <label for="_source">Source: <span id="_sourceName"></span></label>
            <textarea id="_source" title="MusicXML" class="content"></textarea>
        </form>
    </div>
    <div class="pure-u-1 pure-u-md-1-3">
        <div>
            <a href="javascript:void(0);" class="pure-button" id="_default">恢复默认</a>
        </div>
        <div style="margin: 4px 0;">
            <label>配置:</label>
        </div>
        <form class="pure-form pure-form-aligned" action="#" id="_cfg" style="margin-right: 10px;">
            <fieldset>
                <div class="pure-control-group">
                    <label for="_name">曲谱名称</label>
                    <input id="_name" name="name" type="text" placeholder="默认" style="width: 150px;">
                </div>
                <div class="pure-control-group">
                    <label for="_name">曲谱作者</label>
                    <input id="_author" name="author" type="text" placeholder="默认" style="width: 150px;">
                </div>
                <div class="pure-control-group">
                    <label for="_instrument_0">第一音轨乐器</label>
                    <select id="_instrument_0" name="instrument0">
                        <option value="Piano">钢琴</option>
                        <option value="Zheng">古筝</option>
                        <option value="Tieqin">铁琴</option>
                        <option value="Misc">Misc</option>
                    </select>
                </div>
                <div class="pure-control-group">
                    <label for="_instrument_1">第二音轨乐器</label>
                    <select id="_instrument_1" name="instrument1">
                        <option value="Piano">钢琴</option>
                        <option value="Zheng">古筝</option>
                        <option value="Tieqin">铁琴</option>
                        <option value="Misc">Misc</option>
                    </select>
                </div>
                <div class="pure-control-group">
                    <label for="_instrument_2">第三音轨乐器</label>
                    <select id="_instrument_2" name="instrument2">
                        <option value="Piano">钢琴</option>
                        <option value="Zheng">古筝</option>
                        <option value="Tieqin">铁琴</option>
                        <option value="Misc">Misc</option>
                    </select>
                </div>
                <div class="pure-control-group">
                    <label for="_speed">整体速度(%)</label>
                    <input id="_speed" name="speed" type="number" value="100" placeholder="100" style="width: 100px;">
                </div>
                <div class="pure-control-group">
                    <label for="_repeat">处理反复</label>
                    <input id="_repeat" name="repeat" type="checkbox" checked>
                </div>
            </fieldset>
        </form>
    </div>
    <div class="pure-u-1 pure-u-md-1-3">
        <form class="pure-form pure-form-stacked" action="#">
            <a href="javascript:void(0);" class="pure-button" id="_translate">转化...</a>
            <a href="javascript:void(0);" class="pure-button" id="_anchor">下载...</a>
            <label for="_target">GJM:</label>
            <textarea id="_target" title="GJM" class="content" readonly></textarea>
        </form>
    </div>
    <div class="pure-u-1">
        <div class="message" id="_message" title="信息"></div>
    </div>
    <div class="pure-u-1 notes"></div>
</div>
</body>
</html>
